#include "test.h"
#include "proto1/msg_1.pb.h"
#include "proto2/msg_2.pb.h"
#include <ctime>
#include <sstream>
#include <random>

using namespace google::protobuf;
using namespace google::protobuf::compiler;

static const std::string submsg_name = "SubMsgExample";

std::string random_msg_name()
{
    std::random_device rd;
    std::default_random_engine dre(rd());
    std::uniform_int_distribution<int32_t> int_uniform_dist(1, 2);
    int32_t index = int_uniform_dist(dre);
    std::ostringstream stem;
    stem << "MsgExample_" << index;
    return stem.str();
}

void dump_msg(const google::protobuf::Message * msg)
{
    std::cout << msg->GetTypeName() << "{ " << msg->ShortDebugString() << " }" << std::endl;
}

void dump_msg(const std::shared_ptr<google::protobuf::Message> msg)
{
    std::cout << msg->GetTypeName() << "{ " << msg->ShortDebugString() << " }" << std::endl;
}

int32_t test_msg_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    {
        std::string msg_name = random_msg_name();
        std::shared_ptr<Message> msg = nullptr;
        msg.reset(pbpsr.create_msg(msg_name));
        CHECKPTR_NULL_RETURN(msg, -1);
        std::cout << "has_submsg = " << std::boolalpha << pbpsr.has_field(msg.get(), "submsg") << std::endl;

        Message * sub_msg = pbpsr.mutable_msg(msg.get(), "submsg");
        CHECKPTR_NULL_RETURN(sub_msg, -1);
        pbpsr.set_enum(sub_msg, 101, "ENUM_EXAMPLE", 1);
        dump_msg(msg);
        std::cout << "has_submsg = " << std::boolalpha << pbpsr.has_field(msg.get(), "submsg") << std::endl;
    }

    {
        std::string msg_name = random_msg_name();
        std::shared_ptr<Message> msg = nullptr;
        msg.reset(pbpsr.create_msg(msg_name));
        CHECKPTR_NULL_RETURN(msg, -1);
        std::cout << "has_submsg = " << std::boolalpha << pbpsr.has_field(msg.get(), 1) << std::endl;

        Message * sub_msg = pbpsr.mutable_msg(msg.get(), 1);
        CHECKPTR_NULL_RETURN(sub_msg, -1);
        pbpsr.set_enum(sub_msg, 101, "ENUM_EXAMPLE", 1);
        dump_msg(msg);
        std::cout << "has_submsg = " << std::boolalpha << pbpsr.has_field(msg.get(), 1) << std::endl;
    }

    {
        std::string msg_name = random_msg_name();
        std::shared_ptr<Message> msg = nullptr;
        msg.reset(pbpsr.create_msg(msg_name));
        CHECKPTR_NULL_RETURN(msg, -1);

        Message * submsg = pbpsr.create_msg(submsg_name);
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_enum(submsg, 101, "ENUM_EXAMPLE", 2);
        pbpsr.set_msg(msg.get(), submsg, "submsg");
        dump_msg(msg);
    }

    {
        std::string msg_name = random_msg_name();
        std::shared_ptr<Message> msg = nullptr;
        msg.reset(pbpsr.create_msg(msg_name));
        CHECKPTR_NULL_RETURN(msg, -1);

        Message * submsg = pbpsr.create_msg(submsg_name);
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_enum(submsg, 101, "ENUM_EXAMPLE", 2);
        pbpsr.set_msg(msg.get(), submsg, 1);
        dump_msg(msg);
    }

    {
        std::string msg_name = random_msg_name();
        std::shared_ptr<Message> msg = nullptr;
        msg.reset(pbpsr.create_msg(msg_name));
        CHECKPTR_NULL_RETURN(msg, -1);

        Message * sub_msg = pbpsr.mutable_msg(msg.get(), "submsg");
        CHECKPTR_NULL_RETURN(sub_msg, -1);
        pbpsr.set_enum(sub_msg, 101, "ENUM_EXAMPLE", 1);
        dump_msg(msg);
        std::cout << "has sub_msg:" << std::boolalpha << pbpsr.has_field(msg.get(), "submsg") << ":" << msg->ShortDebugString() << std::endl;
        pbpsr.clear_field(msg.get(), 1);
        std::cout << "has sub_msg:" << std::boolalpha << pbpsr.has_field(msg.get(), "submsg") << ":" << msg->ShortDebugString() << std::endl;
    }

    {
        std::string msg_name = random_msg_name();
        std::shared_ptr<Message> msg = nullptr;
        msg.reset(pbpsr.create_msg(msg_name));
        CHECKPTR_NULL_RETURN(msg, -1);

        Message * sub_msg = pbpsr.mutable_msg(msg.get(), 1);
        CHECKPTR_NULL_RETURN(sub_msg, -1);
        pbpsr.set_enum(sub_msg, 101, "ENUM_EXAMPLE", 1);
        std::cout << "has sub_msg:" << std::boolalpha << pbpsr.has_field(msg.get(), 1) << ":" << msg->ShortDebugString() << std::endl;
        pbpsr.clear_field(msg.get(), 1);
        std::cout << "has sub_msg:" << std::boolalpha << pbpsr.has_field(msg.get(), 1) << ":" << msg->ShortDebugString() << std::endl;
    }

    {
        std::string msg_name = random_msg_name();
        std::shared_ptr<Message> msg = nullptr;
        msg.reset(pbpsr.create_msg(msg_name));
        CHECKPTR_NULL_RETURN(msg, -1);
        std::cout << "size of submsg_list = " << pbpsr.field_size(msg.get(), "submsg_list") << std::endl;

        Message * sub_msg1 = pbpsr.add_msg(msg.get(), "submsg_list");
        CHECKPTR_NULL_RETURN(sub_msg1, -1);
        pbpsr.set_enum(sub_msg1, 101, "ENUM_EXAMPLE", 1);


        Message * sub_msg2 = pbpsr.create_msg(submsg_name);
        CHECKPTR_NULL_RETURN(sub_msg2, -1);
        pbpsr.set_enum(sub_msg2, 101, "ENUM_EXAMPLE", 2);
        pbpsr.add_msg(msg.get(), "submsg_list", sub_msg2);
        dump_msg(msg);

        Message * sub_msg3 = pbpsr.mutable_repeated_msg(msg.get(), "submsg_list", 0);
        pbpsr.set_enum(sub_msg3, 101, "ENUM_EXAMPLE", 2);
        dump_msg(msg);
        std::cout << "size of submsg_list = " << pbpsr.field_size(msg.get(), "submsg_list") << std::endl;
        for (int32_t i = 0; i < pbpsr.field_size(msg.get(), "submsg_list"); ++i)
        {
            const Message * submsg = pbpsr.get_repeated_msg(msg.get(), "submsg_list", i);
            std::cout << "msg:" << i << " " << submsg->ShortDebugString() << std::endl;
        }
    }

    {
        std::string msg_name = random_msg_name();
        std::shared_ptr<Message> msg = nullptr;
        msg.reset(pbpsr.create_msg(msg_name));
        CHECKPTR_NULL_RETURN(msg, -1);
        std::cout << "size of field_2 = " << pbpsr.field_size(msg.get(), 2) << std::endl;

        Message * sub_msg1 = pbpsr.add_msg(msg.get(), 2);
        CHECKPTR_NULL_RETURN(sub_msg1, -1);
        pbpsr.set_enum(sub_msg1, 101, "ENUM_EXAMPLE", 1);


        Message * sub_msg2 = pbpsr.create_msg(submsg_name);
        CHECKPTR_NULL_RETURN(sub_msg2, -1);
        pbpsr.set_enum(sub_msg2, 101, "ENUM_EXAMPLE", 2);
        pbpsr.add_msg(msg.get(), 2, sub_msg2);
        dump_msg(msg);

        Message * sub_msg3 = pbpsr.mutable_repeated_msg(msg.get(), 2, 0);
        pbpsr.set_enum(sub_msg3, 101, "ENUM_EXAMPLE", 2);
        dump_msg(msg);
        std::cout << "size of field_2 = " << pbpsr.field_size(msg.get(), 2) << std::endl;
        for (int32_t i = 0; i < pbpsr.field_size(msg.get(), 2); ++i)
        {
            const Message * submsg = pbpsr.get_repeated_msg(msg.get(), 2, i);
            std::cout << "msg:" << i << " " << submsg->ShortDebugString() << std::endl;
        }
    }
    return 0;
}

int32_t test_enum_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    const std::string field_name = "e_val";
    const std::string repeated_field_name = "e_val_list";
    const std::string enum_name = "ENUM_EXAMPLE";
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_enum(submsg.get(), field_name, enum_name, "ENUM_EXAMPLE_V1");
        dump_msg(submsg);
        pbpsr.add_enum(submsg.get(), repeated_field_name, enum_name, "ENUM_EXAMPLE_V2");
        dump_msg(submsg);
        pbpsr.set_repeated_enum(submsg.get(), repeated_field_name, enum_name, 0, "ENUM_EXAMPLE_V3");
        dump_msg(submsg);
        std::cout << pbpsr.get_enum_name(submsg.get(), field_name) << ":" << pbpsr.get_enum_number(submsg.get(), field_name) << std::endl;
        std::cout << pbpsr.get_repeated_enum_name(submsg.get(), repeated_field_name, 0) << ":" << pbpsr.get_repeated_enum_number(submsg.get(), repeated_field_name, 0) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_enum(submsg.get(), 101, enum_name, "ENUM_EXAMPLE_V1");
        dump_msg(submsg);
        pbpsr.add_enum(submsg.get(), 102, enum_name, "ENUM_EXAMPLE_V2");
        dump_msg(submsg);
        pbpsr.set_repeated_enum(submsg.get(), 102, enum_name, 0, "ENUM_EXAMPLE_V3");
        dump_msg(submsg);
        std::cout << pbpsr.get_enum_name(submsg.get(), 101) << ":" << pbpsr.get_enum_number(submsg.get(), 101) << std::endl;
        std::cout << pbpsr.get_repeated_enum_name(submsg.get(), 102, 0) << ":" << pbpsr.get_repeated_enum_number(submsg.get(), 102, 0) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_enum(submsg.get(), field_name, enum_name, 1);
        dump_msg(submsg);
        pbpsr.add_enum(submsg.get(), repeated_field_name, enum_name, 2);
        dump_msg(submsg);
        pbpsr.set_repeated_enum(submsg.get(), repeated_field_name, enum_name, 0, 3);
        dump_msg(submsg);
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_enum(submsg.get(), 101, enum_name, 1);
        dump_msg(submsg);
        pbpsr.add_enum(submsg.get(), 102, enum_name, 2);
        dump_msg(submsg);
        pbpsr.set_repeated_enum(submsg.get(), 102, enum_name, 0, 3);
        dump_msg(submsg);
    }
    return 0;
}

int32_t test_string_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    const std::string field_name = "str_val";
    const std::string repeated_field_name = "str_val_list";
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_string(submsg.get(), field_name, "string_1");
        pbpsr.add_string(submsg.get(), repeated_field_name, "string_1");
        pbpsr.add_string(submsg.get(), repeated_field_name, "string_1");
        dump_msg(submsg);
        pbpsr.set_repeated_string(submsg.get(), repeated_field_name, 1, "string_2");
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_string(submsg.get(), repeated_field_name, 1) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_string(submsg.get(), 201, "string_1");
        pbpsr.add_string(submsg.get(), 202, "string_1");
        pbpsr.add_string(submsg.get(), 202, "string_1");
        dump_msg(submsg);
        pbpsr.set_repeated_string(submsg.get(), 202, 1, "string_2");
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_string(submsg.get(), 202, 1) << std::endl;
    }
    return 0;
}

int32_t test_float_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    const std::string field_name = "float_val";
    const std::string repeated_field_name = "float_val_list";
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_float(submsg.get(), field_name, 1.0f);
        pbpsr.add_float(submsg.get(), repeated_field_name, 1.0f);
        pbpsr.add_float(submsg.get(), repeated_field_name, 1.0f);
        dump_msg(submsg);
        pbpsr.set_repeated_float(submsg.get(), repeated_field_name, 1, 2.0f);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_float(submsg.get(), repeated_field_name, 1) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_float(submsg.get(), 301, 1.0f);
        pbpsr.add_float(submsg.get(), 302, 1.0f);
        pbpsr.add_float(submsg.get(), 302, 1.0f);
        dump_msg(submsg);
        pbpsr.set_repeated_float(submsg.get(), 302, 1, 2.0f);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_float(submsg.get(), 302, 1) << std::endl;
    }
    return 0;
}

int32_t test_double_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    const std::string field_name = "double_val";
    const std::string repeated_field_name = "double_val_list";
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_double(submsg.get(), field_name, 1.0);
        pbpsr.add_double(submsg.get(), repeated_field_name, 1.0);
        pbpsr.add_double(submsg.get(), repeated_field_name, 1.0);
        dump_msg(submsg);
        pbpsr.set_repeated_double(submsg.get(), repeated_field_name, 1, 2.0);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_double(submsg.get(), repeated_field_name, 1) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_double(submsg.get(), 401, 1.0);
        pbpsr.add_double(submsg.get(), 402, 1.0);
        pbpsr.add_double(submsg.get(), 402, 1.0);
        dump_msg(submsg);
        pbpsr.set_repeated_double(submsg.get(), 402, 1, 2.0);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_double(submsg.get(), 402, 1) << std::endl;
    }
    return 0;
}

int32_t test_int32_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    const std::string field_name = "int32_val";
    const std::string repeated_field_name = "int32_val_list";
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_int32(submsg.get(), field_name, 1);
        pbpsr.add_int32(submsg.get(), repeated_field_name, 1);
        pbpsr.add_int32(submsg.get(), repeated_field_name, 1);
        dump_msg(submsg);
        pbpsr.set_repeated_int32(submsg.get(), repeated_field_name, 1, 2);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_int32(submsg.get(), repeated_field_name, 1) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_int32(submsg.get(), 501, 1);
        pbpsr.add_int32(submsg.get(), 502, 1);
        pbpsr.add_int32(submsg.get(), 502, 1);
        dump_msg(submsg);
        pbpsr.set_repeated_int32(submsg.get(), 502, 1, 2);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_int32(submsg.get(), 502, 1) << std::endl;
    }
    return 0;
}

int32_t test_uint32_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    const std::string field_name = "uint32_val";
    const std::string repeated_field_name = "uint32_val_list";
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_uint32(submsg.get(), field_name, 1);
        pbpsr.add_uint32(submsg.get(), repeated_field_name, 1);
        pbpsr.add_uint32(submsg.get(), repeated_field_name, 1);
        dump_msg(submsg);
        pbpsr.set_repeated_uint32(submsg.get(), repeated_field_name, 1, 2);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_uint32(submsg.get(), repeated_field_name, 1) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_uint32(submsg.get(), 601, 1);
        pbpsr.add_uint32(submsg.get(), 602, 1);
        pbpsr.add_uint32(submsg.get(), 602, 1);
        dump_msg(submsg);
        pbpsr.set_repeated_uint32(submsg.get(), 602, 1, 2);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_uint32(submsg.get(), 602, 1) << std::endl;
    }
    return 0;
}

int32_t test_int64_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    const std::string field_name = "int64_val";
    const std::string repeated_field_name = "int64_val_list";
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_int64(submsg.get(), field_name, 1);
        pbpsr.add_int64(submsg.get(), repeated_field_name, 1);
        pbpsr.add_int64(submsg.get(), repeated_field_name, 1);
        dump_msg(submsg);
        pbpsr.set_repeated_int64(submsg.get(), repeated_field_name, 1, 2);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_int64(submsg.get(), repeated_field_name, 1) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_int64(submsg.get(), 701, 1);
        pbpsr.add_int64(submsg.get(), 702, 1);
        pbpsr.add_int64(submsg.get(), 702, 1);
        dump_msg(submsg);
        pbpsr.set_repeated_int64(submsg.get(), 702, 1, 2);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_int64(submsg.get(), 702, 1) << std::endl;
    }
    return 0;
}

int32_t test_uint64_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    const std::string field_name = "uint64_val";
    const std::string repeated_field_name = "uint64_val_list";
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_uint64(submsg.get(), field_name, 1);
        pbpsr.add_uint64(submsg.get(), repeated_field_name, 1);
        pbpsr.add_uint64(submsg.get(), repeated_field_name, 1);
        dump_msg(submsg);
        pbpsr.set_repeated_uint64(submsg.get(), repeated_field_name, 1, 2);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_uint64(submsg.get(), repeated_field_name, 1) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_uint64(submsg.get(), 801, 1);
        pbpsr.add_uint64(submsg.get(), 802, 1);
        pbpsr.add_uint64(submsg.get(), 802, 1);
        dump_msg(submsg);
        pbpsr.set_repeated_uint64(submsg.get(), 802, 1, 2);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_uint64(submsg.get(), 802, 1) << std::endl;
    }
    return 0;
}

int32_t test_bool_func(const protobuf_parser & pbpsr)
{
    std::cout << "-----------------------------------------" << std::endl;
    const std::string field_name = "bool_val";
    const std::string repeated_field_name = "bool_val_list";
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_bool(submsg.get(), field_name, false);
        pbpsr.add_bool(submsg.get(), repeated_field_name, false);
        pbpsr.add_bool(submsg.get(), repeated_field_name, false);
        dump_msg(submsg);
        pbpsr.set_repeated_bool(submsg.get(), repeated_field_name, 1, true);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_bool(submsg.get(), repeated_field_name, 1) << std::endl;
    }
    {
        std::shared_ptr<Message> submsg = nullptr;
        submsg.reset(pbpsr.create_msg(submsg_name));
        CHECKPTR_NULL_RETURN(submsg, -1);
        pbpsr.set_bool(submsg.get(), 901, false);
        pbpsr.add_bool(submsg.get(), 902, false);
        pbpsr.add_bool(submsg.get(), 902, false);
        dump_msg(submsg);
        pbpsr.set_repeated_bool(submsg.get(), 902, 1, true);
        dump_msg(submsg);
        std::cout << pbpsr.get_repeated_bool(submsg.get(), 902, 1) << std::endl;
    }
    return 0;
}

int32_t test_serialize_and_parse(const protobuf_parser & pbpsr)
{
    std::string msg_name = random_msg_name();
    std::cout << "serialize-----------------------------------------" << std::endl;
    std::shared_ptr<Message> msg = nullptr;
    msg.reset(pbpsr.create_msg(msg_name));
    CHECKPTR_NULL_RETURN(msg, -1);
    Message * submsg = pbpsr.mutable_msg(msg.get(), 1);
    pbpsr.set_enum(submsg, 101, "ENUM_EXAMPLE", 1);
    pbpsr.set_string(submsg, 201, "stringstringstringstring");
    pbpsr.set_float(submsg, 301, -1.02f);
    pbpsr.set_double(submsg, 401, 1.2345);
    pbpsr.set_int32(submsg, 501, -1000);
    pbpsr.set_uint32(submsg, 601, 1000);
    pbpsr.set_int64(submsg, 701, -2000);
    pbpsr.set_uint64(submsg, 801, 2000);
    pbpsr.set_bool(submsg, 901, true);
    for (int32_t i = 0; i < 10; ++i)
    {
        Message * new_sub_msg = pbpsr.create_msg(submsg->GetTypeName());
        new_sub_msg->CopyFrom(*submsg);
        pbpsr.add_msg(msg.get(), 2, new_sub_msg);
    }
    //std::cout << msg->ShortDebugString() << std::endl;
    std::string msgdata;
    if (msg->SerializeToString(&msgdata) == false)
    {
        std::cerr << "SerializeToString failed." << std::endl;
        return -1;
    }
    std::cout << "SerializeToString success." << std::endl;
    MsgExample_1 pbmsg;
    if (pbmsg.ParseFromString(msgdata) == false)
    {
        std::cerr << "ParseFromString" << std::endl;
        return -1;
    }
    std::cout << "ParseFromString success." << std::endl;
    dump_msg(&pbmsg);
    if (pbmsg.SerializeToString(&msgdata) == false)
    {
        std::cerr << "SerializeToString failed." << std::endl;
        return -1;
    }
    msg_name = random_msg_name();
    std::shared_ptr<Message> new_msg = nullptr;
    new_msg.reset(pbpsr.create_msg(msg_name));
    if (new_msg->ParseFromString(msgdata) == false)
    {
        std::cerr << "ParseFromString" << std::endl;
        return -1;
    }
    dump_msg(new_msg);
    return 0;
}